home *** CD-ROM | disk | FTP | other *** search
- {*********************************************************}
- {* TstRndWt *}
- {* Copyright (c) Julian M Bucknall 2000 *}
- {* All rights reserved. *}
- {*********************************************************}
- {* Algorithms Alfresco: Weighted random numbers *}
- {*********************************************************}
-
- {Note: this unit is released as freeware. In other words, you are free
- to use this unit in your own applications, however I retain all
- copyright to the code. JMB}
-
- program TstRndWt;
-
- {$APPTYPE CONSOLE}
-
- uses
- SysUtils;
-
- const
- Epsilon = 1E-10;
-
- {===TaaRandomWeightedGenerator=======================================}
- type
- TaaRandomWeightedGenerator = class
- private
- FCount : integer;
- FWeights : array of double;
- protected
- public
- constructor Create(const aWeights : array of double);
- destructor Destroy; override;
-
- function Get : integer;
- end;
- {--------}
- constructor TaaRandomWeightedGenerator.Create(const aWeights : array of double);
- var
- i : integer;
- TotalWeight : double;
- begin
- inherited Create;
- Assert(length(aWeights) <> 0,
- 'An array of weights must be provided');
-
- SetLength(FWeights, length(aWeights));
- TotalWeight := 0.0;
- FCount := succ(High(aWeights));
- for i := 0 to pred(FCount) do begin
- TotalWeight := TotalWeight + aWeights[i];
- FWeights[i] := TotalWeight;
- end;
- if (abs(TotalWeight - 1.0) > Epsilon) then
- raise Exception.Create('The weights to not total 1.0');
- FWeights[pred(FCount)] := 1.0;
- end;
- {--------}
- destructor TaaRandomWeightedGenerator.Destroy;
- begin
- SetLength(FWeights, 0);
- inherited Destroy;
- end;
- {--------}
- function TaaRandomWeightedGenerator.Get : integer;
- var
- Value : double;
- i : integer;
- begin
- Value := Random;
- for i := 0 to pred(FCount) do begin
- if (Value < FWeights[i]) then begin
- Result := succ(i);
- Exit;
- end;
- end;
- {we shouldn't ever get here: this staement is merely to fool the
- compiler into not giving us a warning about the result value}
- Result := FCount;
- end;
- {====================================================================}
-
-
- const
- MaxCount = 1000000;
- var
- RandGen : TaaRandomWeightedGenerator;
- Buckets : array [1..6] of integer;
- i : integer;
- begin
- RandGen := TaaRandomWeightedGenerator.Create([0.1, 0.2, 0.3, 0.2, 0.1, 0.1]);
- try
- FillChar(Buckets, sizeof(Buckets), 0);
- for i := 1 to MaxCount do
- inc(Buckets[RandGen.Get]);
- writeln('Bucket counts and ratios...');
- for i := 1 to 6 do
- writeln(Buckets[i]:6, ' ', Buckets[i]/MaxCount:7:4);
- finally
- RandGen.Free;
- end;
- readln;
- end.
-